package com.dongzili.postgresql.common.aspect;

import com.baomidou.mybatisplus.extension.service.IService;
import com.dongzili.postgresql.common.mybatisplus.MybatisPlusUtil;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

@Service
public class ApiLogService {
    private IService<ApiAccessLog> apiAccessLogService;
    // 内存队列缓存日志（容量可根据业务调整）
    private final BlockingQueue<ApiAccessLog> logQueue = new ArrayBlockingQueue<>(100000);
    // 批量写入阈值
    private static final int BATCH_SIZE = 500;

    // 1. 添加日志到队列（非阻塞，队列满时丢弃或降级）
    public void addLog(ApiAccessLog log) {
        boolean offered = logQueue.offer(log);
        if (!offered) {
            // 队列满时的处理：可记录本地文件或打印警告
            System.err.println("日志队列已满，丢弃一条日志: " + log.getRequestUrl());
        }
    }

    // 2. 异步批量写入数据库（定时执行+达到阈值时触发）
    @Async // 异步执行，不阻塞主线程
    @Scheduled(fixedRate = 5000) // 每5秒检查一次
    public void batchSaveLogs() {
        List<ApiAccessLog> logs = new ArrayList<>(BATCH_SIZE);
        // 从队列中取出最多BATCH_SIZE条日志
        logQueue.drainTo(logs, BATCH_SIZE);
        if (!logs.isEmpty()) {
            if (apiAccessLogService == null){
                this.apiAccessLogService = MybatisPlusUtil.getService(ApiAccessLog.class);
            }
            apiAccessLogService.saveBatch(logs); // 批量保存
        }
    }

    // 3. 应用关闭前，确保剩余日志写入数据库
    @PreDestroy
    public void flushRemainingLogs() {
        List<ApiAccessLog> remainingLogs = new ArrayList<>();
        logQueue.drainTo(remainingLogs);
        if (!remainingLogs.isEmpty()) {
            if (apiAccessLogService == null){
                this.apiAccessLogService = MybatisPlusUtil.getService(ApiAccessLog.class);
            }
            apiAccessLogService.saveBatch(remainingLogs);
        }
    }
}